package menu

import (
	"context"
	"encoding/json"

	v1 "gitee.com/liangziyisheng/caas-platform-mc/api/menu/v1"
	"gitee.com/liangziyisheng/caas-platform-mc/internal/consts"
	"gitee.com/liangziyisheng/caas-platform-mc/internal/model/entity"
	"gitee.com/liangziyisheng/caas-platform-mc/internal/service"
	"gitee.com/liangziyisheng/caas-platform-mc/utility/cache"

	"github.com/gogf/gf/v2/errors/gerror"
)

func (c *ControllerV1) List(ctx context.Context, req *v1.ListReq) (res *v1.ListRes, err error) {
	in := &v1.ListInput{}
	in.AppCode = req.AppCode
	out, err := service.Menu().List(ctx, in)
	if err != nil {
		return nil, err
	}

	res = &v1.ListRes{}

	cc, _ := cache.NewCache()
	cache.InitCache(ctx, consts.InitialCacheKeys.PermissionsKey, false)
	val, err := cc.Get(ctx, consts.InitialCacheKeys.PermissionsKey)
	if err != nil {
		return nil, gerror.NewCode(consts.GetCachedPermissionsFailed)
	}
	permissionStr, ok := val.Val().(string)
	if !ok {
		return nil, gerror.NewCode(consts.ParsePermissionCacheFailed)
	}
	permissionMap := make(map[string]entity.Permission, 0)
	json.Unmarshal([]byte(permissionStr), &permissionMap)

	menuMap := make(map[int64]*v1.MenusTree, 0)
	for _, m := range out.Data {
		menuMap[m.Id] = &v1.MenusTree{
			Id:          m.Id,
			AppCode:     m.AppCode,
			Name:        m.Name,
			Description: m.Description,
			Parent:      m.Parent,
			Path:        m.Path,
			Sort:        m.Sort,
			Type:        m.Type,
			Permissions: []*v1.Pms{},
			Children:    []*v1.MenusTree{},
		}
		for _, p := range permissionMap {
			if m.Id == p.MenuId {
				menuMap[m.Id].Permissions = append(menuMap[m.Id].Permissions, &v1.Pms{
					Id:        p.Id,
					Name:      p.Name,
					Path:      p.Path,
					Operation: p.Operation,
					MenuId:    p.MenuId,
				})
			}
		}
	}
	// 构建树结构
	var roots []*v1.MenusTree
	for _, m := range out.Data {
		node := menuMap[m.Id]
		if m.Parent == 0 {
			// 根节点
			roots = append(roots, node)
		} else if parent, exists := menuMap[m.Parent]; exists {
			// 子节点
			parent.Children = append(parent.Children, node)
		}
	}
	res.Data = roots
	return res, nil
}
